﻿//===============================================================================
// Magic OQL
//===============================================================================
// Copyright ?Magic Thought Corporation. All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// Richie (http://www.cnblogs.com/RicCC)
// March 5, 2008
//===============================================================================

using Antlr.Runtime;
using Antlr.Runtime.Tree;

namespace SQLAnalyticLibrary.Expressions
{
    /// <summary>
    /// </summary>
    public class OrderByClause : CombinedKeywords
    {
        /// <summary>
        /// OrderByClause is a imaginary token.
        /// Ignore to add tokens ORDER and BY to subtree, and combine those token text to this one.
        /// </summary>
        /// <param name="t"></param>
        public OrderByClause(IToken t)
            : this(t, string.Empty)
        {
        }
        /// <summary>
        /// OrderByClause is a imaginary token.
        /// Ignore to add tokens ORDER and BY to subtree, and combine those token text to this one.
        /// </summary>
        /// <param name="t"></param>
        public OrderByClause(IToken t, string text)
            : base(t, text, false, null, false, new int[] { OQLParser.ORDER, OQLParser.BY })
        {
        }

        /// <summary>
        /// Add a white space between tokens ORDER and BY.
        /// </summary>
        /// <param name="count">The count of existing tokens in this expression.</param>
        /// <param name="builder">StringBuilder for the text of this expression.</param>
        /// <param name="exp">The expression to be combined.</param>
        protected override bool PreCombine(int count, System.Text.StringBuilder builder, IToken token)
        {
            Antlr.Runtime.CommonToken t = token as Antlr.Runtime.CommonToken;
            if (t != null)
            {
                if (this.TokenStartIndex <= 0)
                {
                    this.TokenStartIndex = t.StartIndex;
                }
                if (t.StopIndex > this.TokenStopIndex)
                {
                    this.TokenStopIndex = t.StopIndex;
                }
            }
            if (count > 0) builder.Append(" ");
            return true;
        }
        public override Expression DupNode()
        {
            return new OrderByClause(this.Token, this.Text);
        }
        public override void VisitSql(ISqlVisitor visitor)
        {
            visitor.Sql(this.ToString()); //ORDER BY keywords
            visitor.Space();
            this.InternalVisitSql(visitor, true, ","); //items of ORDER BY
        }
        public static bool IsOrderByClause(Expression exp)
        {
            if (exp == null || exp.IsNil) return false;
            return exp.Token.Type == OQLParser.OrderByClause;
        }
        internal static int TreeType
        {
            get
            {
                return OQLParser.OrderByClause;
            }
        }
        public void AddOrderBy(string column, string method)
        {
            OrderByItem item = OqlUtil.CreateOrderByItem(column, method);
            if (item != null)
                this.AddChild(item);
        }
        public void AddOrderBy(string column)
        {
            this.AddOrderBy(column, null);
        }
    }
}